package com.github.obourgain.elasticsearch.http.response.entity.suggest;
import static org.elasticsearch.common.xcontent.XContentParser.Token.END_OBJECT;
import static org.elasticsearch.common.xcontent.XContentParser.Token.FIELD_NAME;
import static org.elasticsearch.common.xcontent.XContentParser.Token.START_OBJECT;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import com.github.obourgain.elasticsearch.http.response.entity.Converter;
public class Suggestions {
private final Map<String, Suggestion> parsed = new HashMap<>();
private final Map<String, XContentBuilder> rawSuggestions = new HashMap<>();
public Collection<String> names() {
return rawSuggestions.keySet();
}
public Completion getCompletion(final String name) {
return findOrCreate(name, new Converter<Completion>() {
@Override
public Completion convert(XContentParser parser) {
return Completion.parse(parser, name);
}
});
}
public Term getTerm(final String name) {
return findOrCreate(name, new Converter<Term>() {
@Override
public Term convert(XContentParser parser) {
return Term.parse(parser, name);
}
});
}
public Phrase getPhrase(final String name) {
return findOrCreate(name, new Converter<Phrase>() {
@Override
public Phrase convert(XContentParser parser) {
return Phrase.parse(parser, name);
}
});
}
public void addRawSuggestion(String name, XContentBuilder rawSuggestion) {
rawSuggestions.put(name, rawSuggestion);
}
private <T extends Suggestion> T findOrCreate(String name, Converter<T> converter) {
@SuppressWarnings("unchecked")
T t = (T) parsed.get(name);
if (t != null) {
return t;
} else {
XContentBuilder builder = rawSuggestions.get(name);
try {
if (builder != null) {
try (XContentParser parser = XContentHelper.createParser(builder.bytes())) {
t = converter.convert(parser);
parsed.put(name, t);
return t;
}
} else {
return null;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/*
parses something like : (with the heading parenthesis)
{
"song-suggest": {
"text": "n",
"completion": {
"field": "suggest"
}
}
}
*/
public static Suggestions parse(XContentParser parser) {
try {
assert parser.currentToken() == START_OBJECT : "expected a START_OBJECT token but was " + parser.currentToken();
Suggestions suggestions = new Suggestions();
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != END_OBJECT) {
if (token == FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == START_OBJECT) {
try (XContentBuilder docBuilder = XContentFactory.contentBuilder(XContentType.JSON)) {
suggestions.addRawSuggestion(currentFieldName, docBuilder.copyCurrentStructure(parser));
}
}
}
return suggestions;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/*
parses something like (e.g. for sub aggs)
"song-suggest": {
"text": "n",
"completion": {
"field": "suggest"
}
}
*/
protected static Pair<String, XContentBuilder> parseInnerSuggestion(XContentParser parser, String aggregationName) {
try {
assert parser.currentToken() == START_OBJECT : "expected a START_OBJECT token but was " + parser.currentToken();
XContentBuilder docBuilder = XContentFactory.contentBuilder(XContentType.JSON);
docBuilder.copyCurrentStructure(parser);
docBuilder.close();
return Pair.of(aggregationName, docBuilder);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}